package main;
import java.awt.Graphics2D;
import java.awt.Color;
import java.util.ArrayList;

public class Location {
	
	private final int ROW_VALUE, COLUMN_VALUE, LENGTH = 20;
	private Color location_color;
	private int f_value = 0, g_value = 0, h_value = 0;
	private Location parentLoc = null;
	private boolean bad_location, reachable;
	public boolean visited = false; 
	public int numTimesIgnored = 0;
	private boolean end_location = false;
	private final int northLimit, southLimit, eastLimit, westLimit;
	
	public Location(int row, int column, boolean isBad)
	{
		ROW_VALUE = row;
		COLUMN_VALUE = column;
		northLimit = ROW_VALUE == 0 ? 0:ROW_VALUE-1;
		southLimit = ROW_VALUE == 29 ? 29: ROW_VALUE+1;
		westLimit = COLUMN_VALUE == 0 ? 0:COLUMN_VALUE-1;
		eastLimit = COLUMN_VALUE == 49 ? 49: COLUMN_VALUE+1;
		bad_location = isBad;
		reachable = !isBad;
		location_color = isBad ? new Color (255, 0, 64): new Color (0, 191, 255);
	}
	public void draw(Graphics2D g)
	{
		g.setColor(location_color);
		g.fillRect(COLUMN_VALUE*LENGTH, ROW_VALUE*LENGTH, LENGTH, LENGTH);
		g.setColor(Color.black);
		if (isStartPoint())
			g.drawString("S",COLUMN_VALUE*LENGTH+6 , ROW_VALUE*LENGTH+14);
		else if (end_location())
			g.drawString("E",COLUMN_VALUE*LENGTH+6 , ROW_VALUE*LENGTH+14);
	}
	public boolean setStartPoint()//Returns true if the start point could not be set
	{
		if (bad_location) return true;	
		Grid.startLoc = this;
		location_color = new Color(255, 191, 0);
		return false;
	}
	public boolean setEndPoint()//Returns true if the start point could not be set
	{
		if (bad_location || isStartPoint()) return true;
		end_location = true;
		Grid.endLoc = this;
		location_color = new Color(255, 0, 191);
		return false;
	}
	public void reset(boolean removeEndPoint)
	{
		if(!location_color.equals(new Color (255, 0, 64)))
		{
			bad_location = false;
			visited = false;
			numTimesIgnored = 0;
			h_value = 0;
			g_value = 0;
			f_value = 0;
			parentLoc = null;
			reachable = true;
			if (removeEndPoint)
			{
				location_color = new Color(0, 191, 255);
				end_location = false;
				if (isStartPoint())
					Grid.startLoc = null;
			}
		} 
	}
	public int row() {
		return ROW_VALUE;
	}
	public int col() {
		return COLUMN_VALUE;
	}
	
	public boolean isBadLocation()
	{return bad_location;}
	
	public void setBadLocation()
	{bad_location = true;}
	
	public boolean end_location()
	{
		return end_location;
	}
	public boolean isStartPoint() {
		return Grid.startLoc == this;
	}
	public int getGValue()
	{return g_value;}
	
	public int getFValue()
	{return f_value;}
	
	
	public boolean isEndLocation()
	{return end_location;}
	
	
	public Location getParent()
	{return parentLoc;}
	
	public void setParent(Location parent)
	{
		parentLoc = parent;
	}
	public void setHeuristicValue(Location endLoc)
	{
		int rowDifference = Math.abs(row() - endLoc.row());
		int colDifference = Math.abs(col() - endLoc.col());
		h_value = (colDifference > rowDifference) ? (rowDifference * 14) + 10 * (colDifference - rowDifference) : (colDifference * 14) + 10 * (rowDifference - colDifference);
		f_value = h_value + g_value;
	}
	public ArrayList<Location> getAdjacentLocations(boolean[][]vision)
	{
		ArrayList<Location> childLocations = new ArrayList<Location>();
		for(int row = northLimit; row <= southLimit; row++)
		{
			for(int col = westLimit; col <= eastLimit; col++)
			{
				if(row != ROW_VALUE || col != COLUMN_VALUE)
				{
					if(vision[row][col]) //if it can see the location it can test to see if its bad
					{
						if(!Grid.grid[row][col].isBadLocation())
							childLocations.add(Grid.grid[row][col]);
					}
					else //otherwise it assumes that it is a good location
						childLocations.add(Grid.grid[row][col]);
				}
			}
		}
		return childLocations;
	}
	public ArrayList<Location> getAdjacentLocations()
	{
		ArrayList<Location> childLocations = new ArrayList<Location>();
		for(int row = northLimit; row <= southLimit; row++)
		{
			for(int col = westLimit; col <= eastLimit; col++)
			{
				if(row != ROW_VALUE || col != COLUMN_VALUE)
				{
						if(!Grid.grid[row][col].isBadLocation())
							childLocations.add(Grid.grid[row][col]);
				}
			}
		}
		return childLocations;
	}
	public void setGValue(int g)
	{g_value = g;}
	
	public boolean isRed()
	{return location_color.equals(new Color(255,0,64));}
	
	public void setToUnreachable()
	{reachable = false;}
	
	public boolean isReachable()
	{return reachable;}
}
